from selenium import webdriver
from selenium.webdriver.firefox.service import Service as FirefoxService
from selenium.webdriver.edge.service import Service as EdgeService
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium.webdriver.edge.options import Options as EdgeOptions
from webdriver_manager.firefox import GeckoDriverManager
from webdriver_manager.microsoft import EdgeChromiumDriverManager
from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import NoAlertPresentException
import time


class GomokuTestBase:
    """Base class for Gomoku automation tests."""

    # Configuration constants
    LOGIN_URL = "http://192.168.217.131:9002/login.html"
    PLAYER1_CREDENTIALS = {"username": "nihao8", "password": "123"}
    PLAYER2_CREDENTIALS = {"username": "nihao2", "password": "123"}
    CELL_SIZE = 30
    OFFSET_X = 15
    OFFSET_Y = 15

    def __init__(self):
        """Initialize Firefox and Edge WebDrivers."""
        self.firefox_driver = self._setup_firefox_driver()
        self.edge_driver = self._setup_edge_driver()

    def _setup_firefox_driver(self):
        """Set up Firefox WebDriver."""
        firefox_options = FirefoxOptions()
        return webdriver.Firefox(
            service=FirefoxService(GeckoDriverManager().install()),
            options=firefox_options
        )

    def _setup_edge_driver(self):
        """Set up Edge WebDriver."""
        edge_options = EdgeOptions()
        return webdriver.Edge(
            service=EdgeService(EdgeChromiumDriverManager().install()),
            options=edge_options
        )

    def login(self, driver, credentials):
        """Log in a player with given credentials."""
        driver.get(self.LOGIN_URL)
        time.sleep(2)  # Wait for page load
        driver.find_element(By.CSS_SELECTOR, "#user_name").send_keys(credentials["username"])
        driver.find_element(By.CSS_SELECTOR, "#password").send_keys(credentials["password"])
        driver.find_element(By.CSS_SELECTOR, "#submit").click()
        time.sleep(1)
        driver.switch_to.alert.accept()
        time.sleep(1)
        driver.switch_to.alert.accept()

    def click_chess_cell(self, driver, row, col, handle_alert=False):
        """
        Click a cell on the chessboard at (row, col).
        Optionally handle alerts if handle_alert=True.
        """
        canvas = driver.find_element("id", "chess")
        x = self.OFFSET_X + (col - 1) * self.CELL_SIZE
        y = self.OFFSET_Y + (row - 1) * self.CELL_SIZE
        actions = ActionChains(driver)
        actions.move_to_element_with_offset(canvas, x, y).click().perform()

        if handle_alert:
            try:
                alert = driver.switch_to.alert
                print(f"Alert detected: {alert.text}")
                alert.accept()
            except NoAlertPresentException:
                pass

    def start_match(self):
        """Start a match by clicking match buttons for both players."""
        self.edge_driver.find_element(By.CSS_SELECTOR, "#match-button").click()
        time.sleep(1)
        self.firefox_driver.find_element(By.CSS_SELECTOR, "#match-button").click()
        time.sleep(1)

    def is_player_turn(self, driver):
        """Check if it's the player's turn."""
        return driver.find_element(By.CSS_SELECTOR, "#screen").text == "轮到己方走棋..."

    def play_chess_sequence(self, first_driver, second_driver, moves_first, moves_second, handle_alert=False):
        """Play a sequence of chess moves alternating between players."""
        for move1, move2 in zip(moves_first, moves_second):
            self.click_chess_cell(first_driver, *move1, handle_alert=handle_alert)
            self.click_chess_cell(second_driver, *move2, handle_alert=handle_alert)

    def return_to_lobby(self):
        """Click 'return to lobby' button for both players."""
        self.edge_driver.find_element(By.CSS_SELECTOR, "#chess_area > div:nth-child(3)").click()
        self.firefox_driver.find_element(By.CSS_SELECTOR, "#chess_area > div:nth-child(3)").click()

    def send_chat_message(self, sender_driver, message):
        """Send a chat message from the sender_driver."""
        sender_driver.find_element(By.CSS_SELECTOR, "#chat_input").send_keys(message)
        sender_driver.find_element(By.CSS_SELECTOR, "#chat_button").click()
        sender_driver.find_element(By.CSS_SELECTOR, "#chat_input").clear()

    def verify_chat_message(self, receiver_driver, expected_message):
        """Verify if the last chat message matches the expected message."""
        p_elements = receiver_driver.find_elements(By.CSS_SELECTOR, "#chat_show p")
        if p_elements:
            last_p_text = p_elements[-1].text
            print(f"Last <p> tag content: {last_p_text}")
            return last_p_text == expected_message
        print("No <p> tags found")
        return False

    def cleanup(self):
        """Close both browsers."""
        self.firefox_driver.quit()
        self.edge_driver.quit()